package server

import (
	"fmt"
	"net"
	"reflect"
	"rpc_server_demo/tools"
)

type RpcServer struct {
	addr  string
	funcs map[string]reflect.Value
}

func NewRpcServer(addr string) *RpcServer {
	return &RpcServer{
		addr:  addr,
		funcs: make(map[string]reflect.Value),
	}
}

func (r *RpcServer) Register(rpcName string, f interface{}) {
	if _, ok := r.funcs[rpcName]; ok {
		return
	}
	r.funcs[rpcName] = reflect.ValueOf(f)
}

func (r *RpcServer) Run() {
	listen, err := net.Listen("tcp", r.addr)
	if err != nil {
		fmt.Println("listen failure,err:", err)
		return
	}
	for {
		conn, err := listen.Accept()
		if err != nil {
			return
		}
		session := tools.NewSession(conn)
		readData, err := session.Read()
		if err != nil {
			return
		}
		//解码
		decodeData, err := tools.Decode(readData)
		if err != nil {
			return
		}
		//判断函数是否存在
		f, ok := r.funcs[decodeData.Name]
		if !ok {
			fmt.Println("函数", decodeData.Name, "不存在")
			return
		}
		inArgs := make([]reflect.Value, len(decodeData.Args))
		for _, v := range decodeData.Args {
			inArgs = append(inArgs, reflect.ValueOf(v))
		}
		out := f.Call(inArgs)
		outArgs := make([]interface{}, len(out))
		for _, v := range out {
			outArgs = append(outArgs, v.Interface())
		}
		resp := tools.RPCData{
			Name: decodeData.Name,
			Args: outArgs,
		}
		encodeData, err := tools.Encode(resp)
		if err != nil {
			return
		}
		err = session.Write(encodeData)
		if err != nil {
			return
		}
	}
}
